package com.example.xiaoshuo_yudu.interceptor;
import com.example.xiaoshuo_yudu.utils.Const;
import com.example.xiaoshuo_yudu.utils.JWTUtil;
import com.example.xiaoshuo_yudu.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import io.micrometer.common.util.StringUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * JWT令牌校验过滤器
 */
@Component
@Slf4j
public class JwtTokenFilter extends OncePerRequestFilter {

    @Value("${xiaoshuo.jwt.key}")
    private String key;

    @Resource
    private JwtUtils jwtUtils;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        // 检查请求是否为放行路径
        if (isPermittedRequest(request)) {
            chain.doFilter(request, response);
            return;
        }
        // 处理需要JWT验证的请求
        String authHeader = request.getHeader("Authorization");
        try {
            if (authHeader != null && authHeader.startsWith(Const.JWT_PREFIX)) {
                String token = authHeader.substring(7);

                if (!StringUtils.isEmpty(token)) {

                    // 解析JWT令牌
                    Claims claims = JWTUtil.parseJWT(key, token);
                    // 获取令牌唯一标识jti
                    String jti = claims.getId();
                    // 检查令牌是否在黑名单中（核心新增逻辑）
                    if (jwtUtils.isTokenBlacklisted(jti)) {
                        log.warn("令牌已被注销，拒绝访问：jti={}", jti);
                        response.setStatus(401); // 未授权
                        return ; // 直接返回，不再继续处理
                    }
                    // 获取用户id
                    Long userId = Long.valueOf(claims.get("userid").toString());
                    String role = claims.get("role").toString();
                    List<GrantedAuthority> authorities = new ArrayList<>();
                    authorities.add(new SimpleGrantedAuthority(role)); 
                    log.info("解析到的角色: {}", role);
                    log.info("设置的权限: {}", authorities);
                     //设置当前登录用户的id,角色
                    UsernamePasswordAuthenticationToken authentication = 
                            new UsernamePasswordAuthenticationToken(userId, null, authorities);

                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    System.out.println("当前登录用户id: " + userId);
                }
            }
        } catch (Exception e) {
            log.error("JWT解析失败: {}", e.getMessage());
            // 这里不直接返回401，让后续过滤器处理
            response.setStatus(401);
        }

        chain.doFilter(request, response);
    }

    // 判断请求是否为放行路径
    private boolean isPermittedRequest(HttpServletRequest request) {
        String path = request.getRequestURI();
        // 排除 logout 接口，让过滤器处理
        if (path.equals("/api/auth/logout")) {
            return false;
        }

        // 检查是否为Swagger相关路径
        if (path.startsWith("/swagger-ui") || path.startsWith("/v3/api-docs") ||
                path.startsWith("/swagger-resources") || path.startsWith("/webjars") ||
                path.equals("/swagger-ui.html") || path.equals("/doc.html")) {
            return true;
        }

        // 检查是否为认证相关路径
        if (path.startsWith("/api/auth/") || path.equals("/error")) {
            return true;
        }
        if (path.startsWith("/api/books") ) {
            return true;
        }
        if (path.startsWith("/api/news") ) {
            return true;
        }
        // 检查是否为OPTIONS请求
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            return true;
        }

        return false;
    }
}